package com.aptemo.webetek.client.widgets.games;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.aptemo.webetek.client.WebetekUserServiceAsync;
import com.aptemo.webetek.client.commands.GotAsynchCallback;
import com.aptemo.webetek.client.commands.impl.GetEventsPagingAction;
import com.aptemo.webetek.client.commands.impl.GetLabelsAction;
import com.aptemo.webetek.client.commands.responses.GotLabelsList;
import com.aptemo.webetek.client.enums.EnumEventStatus;
import com.aptemo.webetek.client.enums.EnumUserRole;
import com.aptemo.webetek.client.events.AddBetEvent;
import com.aptemo.webetek.client.events.SelectedBetEvent;
import com.aptemo.webetek.client.exceptions.BackendException.EErrorCodes;
import com.aptemo.webetek.client.widgets.LoginProposalWidget;
import com.aptemo.webetek.client.widgets.paging.PagingPresenter;
import com.aptemo.webetek.shared.EventBean;
import com.aptemo.webetek.shared.LabelBean;
import com.aptemo.webetek.shared.PagingResult;
import com.aptemo.webetek.shared.UserBean;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.ui.HasWidgets;

public class GamesPagingPresenter
		extends PagingPresenter implements ClickHandler
{

	private HandlerManager			meventBus;
	private WebetekUserServiceAsync	rpcService;
	private GamesDisplay			display;
	private int						pageNo		= 0;
	private String					teamId;
	private String					tagId;

	private List<EventBean>			gameList	= new ArrayList<EventBean>();
	protected ArrayList<LabelBean>	labels;

	// private EnumGameStatus status = EnumGameStatus.ACTIVE;
	private HasWidgets				container;
	private UserBean				currentUser;
	protected Date					searchDate;

	public GamesPagingPresenter(UserBean currentUser, GamesDisplay view, HandlerManager eventbus, WebetekUserServiceAsync rpc, String id, String tagId,
			String filter)
	{
		this(currentUser, view, eventbus, rpc, id, tagId, filter, 0);
	}

	public GamesPagingPresenter(UserBean currentUser, GamesDisplay view, HandlerManager eventBus, WebetekUserServiceAsync rpcService, String teamid,
			String tagId, String filter, int pageNo)
	{
		super(view.getPagingView(), 5);

		this.meventBus = eventBus;
		this.rpcService = rpcService;
		this.display = view;

		init(currentUser, teamid, tagId, filter, pageNo);

		// resetPaging();
	}

	private void bind()
	{
		// // set default status
		display.setStatusValue(EnumEventStatus.ACTIVE);

		display.getLabels().addChangeHandler(new ChangeHandler()
		{
			@Override
			public void onChange(ChangeEvent event)
			{
				resetPaging();
				retrieveList(0);
			}
		});

		// display.getStatusList().addChangeHandler(new ChangeHandler()
		// {
		//
		// @Override
		// public void onChange(ChangeEvent event)
		// {
		// resetPaging();
		// }
		// });

		display.getCreateGameBtn().addClickHandler(this);

		display.getList().addClickHandler(this);

	}

	private void retrieveList(final int page)
	{
		final String destPage = getCursor(page);

		display.getInfoField().setText(display.translate("loading"));

		GetEventsPagingAction action = new GetEventsPagingAction(teamId, display.getSelectedLabelId(), searchDate, display.getStatusFieldValue(), destPage,
				getPageSize());
		rpcService.invoke(action, new GotAsynchCallback<PagingResult<EventBean>>()
		{
			@Override
			public void onSuccess(PagingResult<EventBean> result)
			{
				// paging staff...
				if (result.getTotalCnt() >= 0)
				{
					setPagingTotalSize(result.getTotalCnt());
				}
				pageNo = updatePaging(page, result.getCursor());

				// save game list
				gameList = result.getList();

				display.getInfoField().setText("");
				if ((currentUser != null) && ((currentUser.getRole() == EnumUserRole.ADMIN) || (currentUser.getRole() == EnumUserRole.EDITOR)))
				{
					display.addAdminButtons();
					// TODO add to backend
					// checkWarnings();
				}

				display.updateBets(gameList, teamId, meventBus, rpcService);
			}

			@Override
			public void onError(String message, EErrorCodes code)
			{
				if (code.equals(EErrorCodes.LOGIN_ERROR))
				{
					container.clear();
					container.add(new LoginProposalWidget());
				}
				else
				{
					display.getInfoField().setText(message);
				}
			}

		});

		// reset search date...
		searchDate = null;

	}

	protected void checkWarnings()
	{
		int waitcnt = 0;
		for (EventBean bet : gameList)
		{
			if (bet.getStatus() == EnumEventStatus.WAITINGRESULTS)
			{
				waitcnt++;
			}
		}
		if (waitcnt > 0)
		{
			display.getInfoField().setText("You have " + waitcnt + " waiting results...");
		}
	}

	private void loadLabels()
	{
		GetLabelsAction ac = new GetLabelsAction(teamId);
		rpcService.invoke(ac, new GotLabelsList()
		{

			@Override
			public void onError(String message)
			{
				display.getInfoField().setText("cannotLoadLabels");
			}

			@Override
			public void got(ArrayList<LabelBean> result)
			{
				labels = result;
				display.setLabels(result, tagId);
			}
		});
	}

	@Override
	public void go(HasWidgets container)
	{
		this.container = container;

		container.clear();
		container.add(display.getDisplay());

		bind();

		// 
		retrieveList(pageNo);

		// load labels (asynch) and refresh list...
		loadLabels();

	}

	@Override
	public void onClick(ClickEvent event)
	{
		if (event.getSource() == display.getList())
		{
			int selectedRow = display.getClickedRow(event);

			if (selectedRow >= 0)
			{
				// get it from paging...
				EventBean bet = gameList.get(selectedRow); // getItem(selectedRow);
				String id = bet.getKey();
				meventBus.fireEvent(new SelectedBetEvent(id, teamId));
			}
		}
		else if (event.getSource() == display.getCreateGameBtn())
		{
			meventBus.fireEvent(new AddBetEvent(teamId));
		}

	}

	private void init(UserBean currentUser, String teamid, String tagId, String filter, int pageNo)
	{
		this.teamId = teamid;
		this.pageNo = pageNo;

		// TODO check - don't reset tag id (it's not in history token)
		// this.tagId = tagId;
		this.currentUser = currentUser;

		EnumEventStatus status;
		try
		{
			status = EnumEventStatus.valueOf(filter);
		}
		catch (Exception e)
		{
			status = EnumEventStatus.ACTIVE;
		}
		display.setStatusValue(status);

	}

	public void update(UserBean currentUser, String teamId, String tagId, String filter, int pageNo)
	{
		init(currentUser, teamId, tagId, filter, pageNo);

		retrieveList(pageNo);
		// loadLabels();
	}
}
